package cn.com.mall.product.web.service.impl;

import cn.com.mall.product.web.service.IRedisLockService;
import org.redisson.api.RCountDownLatch;
import org.redisson.api.RLock;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class RedisLockServiceImpl implements IRedisLockService {
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    RedissonClient redissonClient;

    public  String getData() throws InterruptedException {
        String uuid= UUID.randomUUID().toString();
        System.out.println("开始进行加锁:"+Thread.currentThread().getName());
        boolean b=redisTemplate.opsForValue().setIfAbsent("lock",uuid,30000l, TimeUnit.MILLISECONDS);
        if(b){
            System.out.println("加锁成功:"+Thread.currentThread().getName());
            String result= setRedisNum();
            String script="if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" +
                    "then\n" +
                    "    return redis.call(\"del\",KEYS[1])\n" +
                    "else\n" +
                    "    return 0\n" +
                    "end";
            DefaultRedisScript defaultRedisScript =new DefaultRedisScript<Long>(script,Long.class);
            System.out.println("业务处理完成，开始释放锁:"+Thread.currentThread().getName());
            redisTemplate.execute(defaultRedisScript, Arrays.asList("lock"),uuid);
            System.out.println("释放锁成功:"+Thread.currentThread().getName());
            return result;
        }else{
            Thread.sleep(1000);
            return getData();
        }
    }

    @Override
    public String testRedissonLock() {
        RLock lock = redissonClient.getLock("my-lock");
        lock.lock();
        System.out.println("加锁成功:"+Thread.currentThread().getName());

            try {
                Thread.sleep(30000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        System.out.println("开始释放锁:"+Thread.currentThread().getName());
        lock.unlock();

        return "ok";


    }
    @Override
    public String lockDoor(){
        RCountDownLatch latch = redissonClient.getCountDownLatch("anyCountDownLatch");

        latch.trySetCount(5);
        try {
            System.out.println("");
            latch.await();
            System.out.println("放假了。。。。。");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

       return "";

    }

    @Override
    public String gogogo(){
        RCountDownLatch latch = redissonClient.getCountDownLatch("anyCountDownLatch");
        latch.countDown();

        return "";

    }

    private String setRedisNum() {
        String num = redisTemplate.opsForValue().get("num");
        if (!StringUtils.isEmpty(num)) {
            Integer i = Integer.valueOf(num);
            i = i + 1;
            redisTemplate.opsForValue().set("num", i.toString());
            return i.toString();
        }
        redisTemplate.opsForValue().set("num", "0");
        return "0";
    }

    @Override
    public String park() {
        RSemaphore semaphore = redissonClient.getSemaphore("semaphore");
        try {
            semaphore.acquire(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("获取了3个停车位。。。。。");
        return "park";

    }



    @Override
    public String go(){
        RSemaphore semaphore = redissonClient.getSemaphore("semaphore");
        semaphore.release();
        System.out.println("释放了一个停车位。。。");
        return "go";
    }

}
